﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

using SharedGenomics.Workbench.Core;
using SharedGenomics.Core;

namespace SharedGenomics.Workbench.PresentationModel
{
    public class PresentationTransferObject : INotifyPropertyChanged
    {
        private IDictionary<string, object> _propertyValues;

        public PresentationTransferObject()
        {
            this._propertyValues = new Dictionary<string, object>();
            this.PropertyChanged += delegate { };
        }

        protected T GetPropertyValue<T>(string propertyName)
        {
            propertyName.ThrowIfNull("propertyName");

            return this._propertyValues.ContainsKey(propertyName) 
                    ? (T)this._propertyValues[propertyName]
                    : default(T);
        }

        protected void SetPropertyValue(string propertyName, object value)
        {
            propertyName.ThrowIfNull("propertyName");

            object existingValue = this._propertyValues.ContainsKey(propertyName) ? this._propertyValues[propertyName] : null;
            bool propertyChanging = !Object.Equals(existingValue, value);

            //update value
            this._propertyValues[propertyName] = value;

            //raise property changed event if required
            if (propertyChanging)
            {
                this.NotifyPropertyChanged(propertyName);
                this.Validate();
            }
        }

        protected void NotifyPropertyChanged(string propertyName)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        protected virtual void Validate(IValidationErrorCollection validationErrors)
        {
        }

        public bool Validate()
        {
            IValidationErrorCollection validationErrors = new ValidationErrorCollection();
            this.Validate(validationErrors);
            this.ValidationChanged.Raise(this, new ValidationErrorsNotificationEventArgs(validationErrors));
            return validationErrors.IsValid;
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public event EventHandler<ValidationErrorsNotificationEventArgs> ValidationChanged;
    }
}
